//	--------------------------------------------------------------------
//	Copyright(C) 2006,2007 Zhao Yukun. All rights reserved.
//	This file is a part of the Xeres system.
//	Xeres 2007
//	Contact : xeres.engine@gmail.com
//	$(reservedInfo)
//	$(reservedDeclaration)
//	--------------------------------------------------------------------
///	@file	<IGuiControl.cpp>
///	@path	~/src/gui/
///	@date	2008/05/20
///	@desc	.

#include "config/config.h"

#include "gui/IGuiControl.h"
#include "gui/IGuiForm.h"

namespace xeres {

	IMPL_IOBJECT_INTERFACE( IGuiControl );

	// IGuiControl
	IGuiControl::IGuiControl( const Rect<int>& placement , bool refreshFocus , bool refreshHover , bool activeOrder )
		: m_position( placement.get_min() )
		, m_size( placement.width() , placement.height() )
		, m_parent( NULL )
		, m_enable( true )
		, m_visible( true )
		, m_focus( false )
		, m_hover( false )
		, m_clicked( false )
		, m_refreshFocus( refreshFocus )
		, m_refreshHover( refreshHover )
		, m_activeOrder( activeOrder )
	{
		// register homeless control
	}
	// ~IGuiControl
	IGuiControl::~IGuiControl( void )
	{
		// deregister homeless control
	}
	// GetPosition
	Pair<int> IGuiControl::GetPosition( void )
	{
		return m_position;
	}
	// SetPosition
	bool IGuiControl::SetPosition( const Pair<int>& pos )
	{
		UpdateControl();

		m_position = pos;

		// Notify pos change.
		OnPos();

		UpdateControl();
		return true;
	}
	// GetScreenPosition
	Pair<int> IGuiControl::GetScreenPosition( void )
	{
		Pair<int> pos = GetPosition();
		RefWeak<IGuiForm> parent = GetParent();
		if( parent.IsValid() )
			pos += parent->GetScreenPosition();
		return pos;
	}
	// GetSize
	Pair<int> IGuiControl::GetSize( void )
	{
		return m_size;
	}
	// SetSize
	bool IGuiControl::SetSize( const Pair<int>& size )
	{
		UpdateControl();

		m_size = size;
		
		// Notify size change.
		OnSize();

		UpdateControl();
		return true;
	}
	// GetRect
	Rect<int> IGuiControl::GetRect( void )
	{
		if( m_size.x > 0 && m_size.y > 0 )
			return Rect<int>( 0 , 0 , m_size.x - 1 , m_size.y - 1 );
		else
			return Rect<int>();
	}
	// GetBound
	Rect<int> IGuiControl::GetBound( void )
	{
		if( m_size.x > 0 && m_size.y > 0 )
			return Rect<int>( 0 , 0 , m_size );
		else
			return Rect<int>();
	}
	// GetPlacement
	Rect<int> IGuiControl::GetPlacement( void )
	{
		return make_rect( m_position.x , m_position.y , m_size.x , m_size.y );
	}
	// SetPlacement
	bool IGuiControl::SetPlacement( const Rect<int>& placement )
	{
		UpdateControl();

		SetPosition( placement.get_min() );
		SetSize( Pair<int>( placement.width() , placement.height() ) );

		UpdateControl();
		return true;
	}
	// GetParent
	RefWeak<IGuiForm> IGuiControl::GetParent( void )
	{
		return m_parent;
	}
	// SetParent
	bool IGuiControl::SetParent( RefWeak<IGuiForm> parent )
	{
		if( m_parent.IsValid() )
			return false;

		m_parent = parent;
		return true;
	}
	// GetVisible
	bool IGuiControl::GetVisible( void )
	{
		return m_visible;
	}
	// SetVisible
	bool IGuiControl::SetVisible( bool visible )
	{
		m_visible = visible;

		// Notify visibility change.
		OnVisible( visible );

		UpdateControl();
		return true;
	}
	// GetEnable
	bool IGuiControl::GetEnable( void )
	{
		return m_enable;
	}
	// SetMute
	bool IGuiControl::SetEnable( bool enable )
	{
		m_enable = enable;

		// Notify enable change.
		OnEnable( enable );

		UpdateControl();
		return true;
	}
	// GetFocus
	bool IGuiControl::GetFocus( void )
	{
		return m_focus;
	}
	// SetFocus
	bool IGuiControl::SetFocus( bool focus )
	{
		m_focus = focus;

		// Notify focus change.
		OnFocus( focus );

		UpdateControl();
		return true;
	}
	// GetHover
	bool IGuiControl::GetHover( void )
	{
		return m_hover;
	}
	// Close
	void IGuiControl::Close( void )
	{
		if( m_parent.IsValid() )
			m_parent->DelChild( this );
		OnClose();
	}
	// OnKeyInput
	HandleInput IGuiControl::OnKeyInput( Updater& updater )
	{
		return INPUT_UNHANDLED;
	}
	// OnMouseInput
	HandleInput IGuiControl::OnMouseInput( Updater& updater )
	{
		return INPUT_UNHANDLED;
	}
	// OnMouseEnter
	void IGuiControl::OnMouseEnter( Updater& updater , RefWeak<IGuiComp> last )
	{
		m_hover = true;
		if( m_refreshHover )
		{
			UpdateControl();
		}
		OnMouseOver( m_hover );
		//TRACE_INFO( _S("Mouse Enter %s") , GetClassName().c_str() );
	}
	// OnMouseLeave
	void IGuiControl::OnMouseLeave( Updater& updater , RefWeak<IGuiComp> next )
	{
		m_hover = false;
		if( m_refreshHover )
		{
			UpdateControl();
		}
		OnMouseOver( m_hover );
		//TRACE_INFO( _S("Mouse Leave %s") , GetClassName().c_str() );
	}
	// OnMouseHover
	void IGuiControl::OnMouseHover( Updater& updater )
	{
		TRACE_INFO( _S("Hover %s") , GetClassName().c_str() );
	}
	// OnFocusIn
	void IGuiControl::OnFocusIn( Updater& updater , RefWeak<IGuiComp> last )
	{
		m_focus = true;
		if( m_refreshFocus )
		{
			UpdateControl();
		}

		if( m_activeOrder )
		{
			ActiveComponent();
		}

		// Notify focus change.
		OnFocus( m_focus );

		//TRACE_INFO( _S("Focus In %s") , GetClassName().c_str() );
	}
	// OnFocusOut
	void IGuiControl::OnFocusOut( Updater& updater , RefWeak<IGuiComp> next )
	{
		m_focus = false;
		if( m_refreshFocus )
		{
			UpdateControl();
		}

		// Notify focus change.
		OnFocus( m_focus );

		//TRACE_INFO( _S("Focus Out %s") , GetClassName().c_str() );
	}
	// UpdateControl
	void IGuiControl::UpdateControl( void )
	{
		if( m_parent.IsValid() && GetVisible() )
		{
			Rect<int> bound = GetBound();
			if( !bound.is_empty() )
				m_parent->RequestUpdate( this , bound );
		}
	}
	// EnableActiveOrder
	void IGuiControl::EnableActiveOrder( bool enable )
	{
		m_activeOrder = enable;
	}
	// Tick
	void IGuiControl::Tick( Updater& updater , float dTime )
	{
		FATAL_ABORT( L"IGuiControl::Tick: Function must be overrided to call" );
	}
	// Draw
	void IGuiControl::Draw( Composition& composition )
	{
		FATAL_ABORT( L"IGuiControl::Draw: Function must be overrided to call" );
	}
	// OnSize
	void IGuiControl::OnSize( void )
	{
	}
	// OnPos
	void IGuiControl::OnPos( void )
	{
	}
	// OnVisible
	void IGuiControl::OnVisible( bool /*visible*/ )
	{
	}
	// OnEnable
	void IGuiControl::OnEnable( bool /*enable*/ )
	{
	}
	// OnFocus
	void IGuiControl::OnFocus( bool /*focusing*/ )
	{
	}
	// OnMouseOver
	void IGuiControl::OnMouseOver( bool /*hovering*/ )
	{
	}
	// OnClose
	void IGuiControl::OnClose( void )
	{
	}

} // namespace xeres
